<?php
/**
 * Func-generator v0.1
 *
 * 批处理任务文件解释器，将以/docs/jobs-spec-v*.*.txt规范说明的方式编写的任务文件转换成任务
 * 队列数组，提交到func-generator.
 *
 * @auth: daer@xiaee.com
 * @date: 2011/03/25
 *
 */

define('JOBS_INSTRUCTION_SET_DEFINITION', 0x01);
define('JOBS_INSTRUCTION_MODULE_ENTRY', 0x02);


function jobs_parse($data, &$result = array()) {
    global $logger;

    $rv = 0;

    // 1. 移除所有的注释
    $data = trim($data);
    $comment_pattern = '/(?<!\\\\)#[^\\n]*?(?:\\n|$)/';
    if (preg_match($comment_pattern, $data)) {
        $data = preg_replace($comment_pattern, '', $data);
    }

    // 2. 移除续行第一个非空字符前的空白字符和回车字符
    $space_pattern = '/\\\\\\n\\s+|(?<=^|\\n)\s+\\n|\\r/';
    if (preg_match($space_pattern, $data)) {
        $data = preg_replace($space_pattern, '', $data);
    }

    // 3. 合并多个空行
    $blank_pattern = '/\n+/';
    if (preg_match($blank_pattern, $data)) {
        $data = preg_replace($blank_pattern, "\n", $data);
    }

    $data_lines = explode("\n", $data);
    $module_cur = null;
    foreach ($data_lines as $no=>$line) {
        $line = trim($line);

        if ($line == '') {
            continue;
        }
        // block terminator
        else if ($line == '}') {
            if (is_null($module_cur)) {
                $logger->error("Incorrect block terminator near '%s'\n", $line);

                return -1;
            }

            $result[] = $module_cur;
            $module_cur = null;
        }
        // instruction definition
        else if (preg_match('/^([-\w]+)\s+(.+)$/', $line, $m1)) {
            $rv += 1;
            if ($m1[1] == 'module-entry') {
                if (preg_match('/^[\'"]([^\'"]+)[\'"]\s+{$/', $m1[2], $m2)) {
                    if (!is_null($module_cur)) {
                        $logger->error("Illegal nested block near '%d'\n", $line);

                        return -1;
                    }

                    $module_cur = array(
                        'type' => JOBS_INSTRUCTION_MODULE_ENTRY,
                        'data' => array(
                            'name' => $m2[1]
                        )
                    );
                }
                else {
                    $logger->error("Syntax error occurred near '%s'\n", $line);

                    return -1;
                }
            }
            else if ($m1[1] == 'set') {
                if (preg_match('/^\\s*([^=]+?)\\s*=\\s*(.*)\\s*$/', $m1[2], $m2)) {
                    if (!is_null($module_cur)) {
                        $module_cur['data'][$m2[1]] = $m2[2];
                    }
                    else {
                        $result[] = array(
                            'type' => JOBS_INSTRUCTION_SET_DEFINITION,
                            'data' => array(
                                $m2[1] => $m2[2]
                            )
                        );
                    }
                }
                else {
                    $logger->error("Syntax error occurred near '%s'\n", $line);

                    return -1;
                }
            }
            else {
                $logger->error("Unsupported instruction found near '%s'\n", $line);

                return -1;
            }
        }
        // syntax error
        else {
            $logger->error("Syntax error occurred near '%s'\n", $line);

            return -1;
        }
    }

    return $rv;
}


function jobs_test() {
    $data = file_get_contents(dirname(__FILE__).'/../data/data.cfg');

    jobs_parse($data, $result);

    var_export($result);
}


